/**********************************************************************\

 Copyright 2012 Diggory Blake

 This file is part of klip-engine

 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 3 of the License, or
 (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.

\**********************************************************************/

#include "kbox2dcontroller.h"
#include "kactor.h"

void kBox2DController::update() {
	for (auto i = getActors().begin(); i != getActors().end(); i++) {
		kActorData* data = (kActorData*)getActorData(*i);
		updateTransform(*i, data);
	}
}
void kBox2DController::onActorAdded(kActor* actor) {
	kController::onActorAdded(actor);

	kActorData* data = new kActorData();
	setActorData(actor, data);
	updateTransform(actor, data);
}
void kBox2DController::onActorRemoved(kActor* actor) {
	delete (kActorData*)getActorData(actor);
	setActorData(actor, 0);

	kController::onActorRemoved(actor);
}
void kBox2DController::updateTransform(kActor* actor, const kActorData* data) {
	kMat3x3 mat = _globalTransform;
	if (data->body) {
		mat = mat*convertTransform(data->body->GetTransform());
	}
	mat = mat*data->localTransform;

	setActorTransform(actor, mat);
}
void kBox2DController::setBody(kActor* actor, b2Body* body) {
	kActorData* data = (kActorData*)getActorData(actor);
	data->body = body;

	updateTransform(actor, data);
}
void kBox2DController::setLocalTransform(kActor* actor, const kMat3x3& transform) {
	kActorData* data = (kActorData*)getActorData(actor);
	data->localTransform = transform;

	updateTransform(actor, data);
}
b2Body* kBox2DController::getBody(kActor* actor) {
	kActorData* data = (kActorData*)getActorData(actor);

	return data->body;
}
const kMat3x3& kBox2DController::getLocalTransform(kActor* actor) {
	kActorData* data = (kActorData*)getActorData(actor);

	return data->localTransform;
}
kBox2DController::kBox2DController() {
}
kMat3x3 kBox2DController::convertTransform(const b2Transform& transform) {
	return kMat3x3(
		transform.q.c,	-transform.q.s,	transform.p.x,
		transform.q.s,	transform.q.c,	transform.p.y,
		0.0f,			0.0f,			1.0f
		);
}
b2Transform kBox2DController::convertTransform(const kMat3x3& transform) {
	kVec2 pos;
	float angle;
	decompose(transform, &pos, 0, &angle);
	return b2Transform(convertVec2(pos), b2Rot(angle));
}
